package EurekaAnalyzer;
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
import java.util.Vector;
import java.io.Serializable;
/**
 * 
 * @author Xenophon
 * @version 2009-12-4
 * <p>The IDInformation class record information for every<br>
 * known id. Including its name, when it replys a post,when<br>
 * it posts a new topic and all the boards it feels comfortably<br>
 * For every such board,the number of appearance is record too.<br>
 * So,a weight scoring that board can calculated from the record<br>
 * to tell which is the id's most favorite board.  
 * <p>The id's friend is also recorded here,by friend, it means<br>
 * the ids who reply the current id's post,so that relation is<br>
 * directed.
 *
 */
public class IDInformation implements Serializable{
	/**
	 * a unique id string 
	 */
	private String id; 
	private int    scc_id = 0;
	private int    cluster_id = 0;
	public class ScoredBoard implements Serializable{
		public String board;
		public int   appearanceCnt = 0;
	}
	/**
	 *all the boards the id has ever appeared
     *each board has a score calculated
     *by the frequency of the id's appearance.
     *Of course, there should be a time attenuation
     *factor in the calculation.
	 */
	private HashMap<String,ScoredBoard> boards = new HashMap<String, ScoredBoard>();
	/**
	 *The id's friends. We suppose the friendship
     *relation is directed. If A replies B's post
     *then we suppose A "knows" B.
	 */

	//private class Friend{
		/**How many times the "Friend" named "id” replies his post*/
	//	public int cnt;
		/**id*/
	//	public String id;              
    //	}
    
	private HashMap<String,Integer> friends = new HashMap<String,Integer>(); 
	
	
	/**
	 *Once the id post a topic or replies a topic
     *we record the time.The format is like:
     *         2009年12月3日 08:53:20
	 */
	private class ActionRecord implements Serializable{
		public String time;
		public String board;
	}
	private Vector<ActionRecord> postTimeStamp = new Vector<ActionRecord>();
	/**similar as above except that it record reply*/ 
	private Vector<ActionRecord> replyTimeStamp = new Vector<ActionRecord>();
	
	public IDInformation(String id) {
		// TODO Auto-generated constructor stub
		this.id = id;
		postTimeStamp = new Vector<ActionRecord>();
		replyTimeStamp = new Vector<ActionRecord>();
	}
	
	/**
	 * <p>append a board record information <br>
	 * if there is a record in the map, then just accumulate the record
	 * otherwise, we create a new record for the board,by default,the new
	 * record has score and appearanceCnt assigned 0.
	 * @param board board identifier like pieBridge:)
	 * @return  
	 */
	public void AppendBoard(String board)
	{
		if (boards.containsKey(board)) {
			ScoredBoard ii = boards.remove(board);
			ii.appearanceCnt++;
			boards.put(board, ii);
		}else{
			ScoredBoard ii = new ScoredBoard();
			ii.board = board;
			ii.appearanceCnt=1;
			boards.put(board, ii);
		}
	}
	/**
	 * Record the id's replying action. Such a record mean
	 * the id reply a topic at that time "time" and on the
	 * "board" board 
	 * @param time  Format:2009年12月3日 08:53:20
	 * @param board board identifier
	 */
	public void AppendReply(String time,String board)
	{
		ActionRecord ar = new ActionRecord();
		ar.board = board;
		ar.time = time;
		replyTimeStamp.add(ar);
	}
	/**
	 * Similar as the {@link #AppendReply(String, String)} except that
	 * now it record the posting action.
	 * @param time  Format:2009年12月3日 08:53:20
	 * @param board board identifier
	 */
	public void AppendPost(String time, String board)
	{
		ActionRecord ar = new ActionRecord();
		ar.board = board;
		ar.time =time;
		postTimeStamp.add(ar);
	}
	
	public void AppendFriend(String id)
	{
		if(this.id.equals(id))
			return;
		int cnt = 1;
		if (friends.containsKey(id)) {
			cnt = friends.remove(id);
			cnt++;
		}
		friends.put(id, cnt);
	}
	
	/**
	 * Return the current ID
	 * @return
	 */
	public String GetID()
	{
		return id;
	}
	
	/**
	 * Return the number of the appearance in a given board
	 * @param board
	 * @return
	 */
	public int GetAppearanceByBoard(String board)
	{
		if (boards.containsKey(board)) {
			return boards.get(board).appearanceCnt;
		}
		return 0;
	}
	
	public int GetPostCnt()
	{
		return postTimeStamp.size();
	}
	
	public int GetReplyCnt()
	{
		return replyTimeStamp.size();
	}
	
	public int GetFriendCount()
	{
		return friends.size();
	}
	
	public HashMap<String, Integer> GetFriendsWhoKnownMe()
	{
		return friends;
	}
	
	public void ShowFriends()
	{
		Set<String> keySet = friends.keySet();
		for(String name:keySet)
			System.out.println(name);
	}
	
	public void Clear()
	{
		boards.clear();
		friends.clear();
		postTimeStamp.clear();
		replyTimeStamp.clear();
	}
	
	public int GetSCCID(){return scc_id;}
	public int GetClusterID(){return cluster_id;}
	public void SetSCCID(int scc_id){this.scc_id = scc_id;}
	public void SetClusterID(int cluster_id){this.cluster_id = cluster_id;}
	public Collection<ScoredBoard> GetBoards(){return  boards.values();}
}
